describe 'utils.gmap-util', ->
  beforeEach ->
    module 'uiGmapgoogle-maps.directives.api.utils'
    module 'uiGmapgoogle-maps.mocks'
    inject [ 'uiGmapGmapUtil', 'GoogleApiMock', (GmapUtil, GoogleApiMock) =>
      @subject = GmapUtil
      @gmap = new GoogleApiMock()
      @gmap.mockAPI()
      @gmap.mockMVCArray()
      @gmap.mockPoint()
      @gmap.mockLatLng()
      @gmap.mockLatLngBounds()
    ]

  describe 'should validate the path correctly', ->
    it 'latlong', ->
      latlong = {longitude: 45, latitude: -27}
      expect(@subject.validatePath([latlong, latlong])).toEqual(true)
      expect(@subject.validatePath([latlong])).toEqual(false)
    it 'empty array', ->
      expect(@subject.validatePath([])).toEqual(false)
    it 'array of invalid objects', ->
      expect(@subject.validatePath([
        {},
        {}
      ])).toEqual(false)
    it 'Polygon', ->
      expect(@subject.validatePath({type: 'Polygon'})).toEqual(false)
      expect(@subject.validatePath({type: 'Polygon', coordinates: [[1, 2] for [1..4]]})).toEqual(true)
      expect(@subject.validatePath({type: 'Polygon', coordinates: [[1, 2] for [1..1]]})).toEqual(false)
    it 'Polygon', ->
      expect(@subject.validatePath({type: 'LineString', coordinates: [1, 2] for [1..2]})).toEqual(true)
      expect(@subject.validatePath({type: 'LineString', coordinates: [1, 2] for [1..1]})).toEqual(false)
      expect(@subject.validatePath({type: 'LineString', coordinates: [] for [1..2]})).toEqual(false)
    it 'foo', ->
      expect(@subject.validatePath({type: 'foo', coordinates: []})).toEqual(false)


  describe 'should validate coordinates correctly', ->
    it 'basic', ->
      expect(@subject.validateCoords()).toEqual(false)
      expect(@subject.validateCoords([1, 2])).toEqual(true)
      expect(@subject.validateCoords([])).toEqual(false)

    it 'type:Point', ->
      expect(@subject.validateCoords({type: 'Point', coordinates: [1, 2]})).toEqual(true)
      expect(@subject.validateCoords({type: 'Point', coordinates: []})).toEqual(false)
    it 'type:foo, no lat lon', ->
      expect(@subject.validateCoords({type: 'foo', coordinates: []})).toEqual(false)
    it 'type:foo, w lat lon', ->
      expect(@subject.validateCoords( type: 'foo', latitude: 45, longitude:150 )).toEqual true

  describe 'should evaluate truthiness correctly', ->
    it 'true', ->
      expect(@subject.isTrue(true)).toEqual(true)
    it '"true"', ->
      expect(@subject.isTrue('true')).toEqual(true)
    it '1', ->
      expect(@subject.isTrue(1)).toEqual(true)
    it '"TRUE"', ->
      expect(@subject.isTrue("TRUE")).toEqual(true)
    it '"y"', ->
      expect(@subject.isTrue('y')).toEqual(true)
    it 'undefined', ->
      expect(@subject.isTrue()).toEqual(false)
    it 'null', ->
      expect(@subject.isTrue(null)).toEqual(false)
    #falses to be false
    it '"false"', ->
      expect(@subject.isTrue('false')).toEqual(false)
    it '"FALSE"', ->
      expect(@subject.isTrue('FALSE')).toEqual(false)
    it '0', ->
      expect(@subject.isTrue(0)).toEqual(false)
    it '"n"', ->
      expect(@subject.isTrue('n')).toEqual(false)
    it '"N"', ->
      expect(@subject.isTrue('N')).toEqual(false)
    it '"no"', ->
      expect(@subject.isTrue('no')).toEqual(false)
    it '"NO"', ->
      expect(@subject.isTrue('NO')).toEqual(false)
    it 'false', ->
      expect(@subject.isTrue(false)).toEqual(false)

  describe 'should evaluate false correctly', ->
    it '"false"', ->
      expect(@subject.isFalse('false')).toEqual(true)
    it '"FALSE"', ->
      expect(@subject.isFalse('FALSE')).toEqual(true)
    it '0', ->
      expect(@subject.isFalse(0)).toEqual(true)
    it '"n"', ->
      expect(@subject.isFalse('n')).toEqual(true)
    it '"N"', ->
      expect(@subject.isFalse('N')).toEqual(true)
    it '"no"', ->
      expect(@subject.isFalse('no')).toEqual(true)
    it '"NO"', ->
      expect(@subject.isFalse('NO')).toEqual(true)
    it 'false', ->
      expect(@subject.isFalse(false)).toEqual(true)
    #expect truthies to be false
    it 'true', ->
      expect(@subject.isFalse(true)).toEqual(false)
    it '"true"', ->
      expect(@subject.isFalse('true')).toEqual(false)
    it '1', ->
      expect(@subject.isFalse(1)).toEqual(false)
    it '"TRUE"', ->
      expect(@subject.isFalse("TRUE")).toEqual(false)
    it '"y"', ->
      expect(@subject.isFalse('y')).toEqual(false)
    #expect null and undefined
    it 'undefined', ->
      expect(@subject.isFalse()).toEqual(false)
    it 'null', ->
      expect(@subject.isFalse(null)).toEqual(false)

  describe 'should evaluate falsiness correctly', ->
    it '"false"', ->
      expect(@subject.isFalsy('false')).toEqual(true)
    it '"FALSE"', ->
      expect(@subject.isFalsy('FALSE')).toEqual(true)
    it '0', ->
      expect(@subject.isFalsy(0)).toEqual(true)
    it '"n"', ->
      expect(@subject.isFalsy('n')).toEqual(true)
    it '"N"', ->
      expect(@subject.isFalsy('N')).toEqual(true)
    it '"no"', ->
      expect(@subject.isFalsy('no')).toEqual(true)
    it '"NO"', ->
      expect(@subject.isFalsy('NO')).toEqual(true)
    it 'false', ->
      expect(@subject.isFalsy(false)).toEqual(true)
    #expect truthies to be false
    it 'true', ->
      expect(@subject.isFalsy(true)).toEqual(false)
    it '"true"', ->
      expect(@subject.isFalsy('true')).toEqual(false)
    it '1', ->
      expect(@subject.isFalsy(1)).toEqual(false)
    it '"TRUE"', ->
      expect(@subject.isFalsy("TRUE")).toEqual(false)
    it '"y"', ->
      expect(@subject.isFalsy('y')).toEqual(false)
    #expect null and undefined
    it 'undefined', ->
      expect(@subject.isFalsy()).toEqual(true)
    it 'null', ->
      expect(@subject.isFalsy(null)).toEqual(true)


  it 'should convert path points correctly', ->
    latlong = {longitude: 45, latitude: -27}
    expect(@subject.convertPathPoints([]).getLength()).toEqual(0)
    expect(@subject.convertPathPoints([latlong]).getLength()).toEqual(1)
    expect(@subject.convertPathPoints({type: 'Polygon', coordinates: [[1, 2] for [1..4]]}).getLength()).toEqual(4)
    expect(@subject.convertPathPoints({type: 'LineString', coordinates: [1, 2] for [1..4]}).getLength()).toEqual(4)

  it '(getLabelPositionPoint) should convert decimal coordinates separated by a space into a map Point object', ->
    testCases = [
      { input: '22 0', expected: { x: 22, y: 0 } }
      { input: '1 2', expected: { x: 1, y: 2 } }
      { input: '1.0 2.3', expected: { x: 1.0, y: 2.3 } }
      { input: '-1 -2', expected: { x: -1, y: -2 } }
    ]
    testCases.forEach (testCase ) =>
      result = @subject.getLabelPositionPoint(testCase.input)
      expect(result.x).toEqual(testCase.expected.x)
      expect(result.y).toEqual(testCase.expected.y)

  it '(getLabelPositionPoint) should ignore coordinate strings not following the format', ->
    testCases = [
      ' 1 2 '
      'a b'
      '1,2'
    ]
    testCases.forEach (testCase)=>
      result = @subject.getLabelPositionPoint(testCase.input)

  it 'should correctly fetch object values using dot-notation', ->
    object = { foo: { sea: 'hawks' }}
    expect(@subject.getPath(object, 'foo.sea')).toEqual('hawks')
    expect(@subject.getPath(object, 'foo.sea.birds')).toEqual(undefined)
    expect(@subject.getPath(object, 'boo.hoo')).toEqual(undefined)
